home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
filesys
/
mfs609s.zoo
/
minit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-25
|
15KB
|
633 lines
/* minit Minix INITializer . Freely distributable Minix filesys creator.
* Copyright S N Henson 1991,1992,1993.
* Use entirely at your own risk ! If it trashes your hard-drive then
* it isn't my fault !
*/
/* Version 0.26 */
#include <mintbind.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <alloc.h>
#include "minixfs/hdio.h"
#include "minixfs/xhdi.h"
#include "minixfs/pun.h"
#define MNAME_MAX 14
int shift,drive=-1;
long numblocks,numinodes,incr=1;
/* various flags */
char protect,sonly,v2,lrecno,tst;
struct hdinfo hdinf;
unsigned char block_buf[1024];
/* Structures we will need */
typedef struct {
unsigned short s_ninodes; /* # usable inodes on the minor device */
unsigned short s_nzones; /* total device size, including bit maps etc */
unsigned short s_imap_blks; /* # of blocks used by inode bit map */
unsigned short s_zmap_blks; /* # of blocks used by zone bit map */
unsigned short s_firstdatazn; /* number of first data zone */
short int s_log_zsize; /* log2 of blocks/zone */
unsigned long s_max_size; /* maximum file size on this device */
short s_magic; /* magic number to recognize super-blocks */
short pad; /* padding */
long s_zones; /* equivalent to 's_nzones' for V2 */
} super_block;
typedef struct { /* directory entry */
unsigned short d_inum; /* inode number */
char d_name[MNAME_MAX]; /* character string */
} dir_struct;
typedef struct { /* disk inode. */
unsigned short i_mode; /* file type, protection, etc. */
unsigned short i_uid; /* user id of the file's owner */
unsigned long i_size; /* current file size in bytes */
unsigned long i_mtime; /* when was file data last changed */
unsigned char i_gid; /* group number */
unsigned char i_nlinks; /* how many links to this file */
unsigned short i_zone[9]; /* block nums for direct, ind, and dbl ind */
} d_inode;
typedef struct {
unsigned short i_mode;
unsigned short i_nlinks;
unsigned short i_uid;
unsigned short i_gid;
unsigned long i_size;
unsigned long i_atime;
unsigned long i_mtime;
unsigned long i_ctime;
long i_zone[10];
} d_inode2;
/* prototypes */
#ifdef __STDC__
# define P(s) s
#else
# define P(s) ()
#endif
void main P((int argc , char **argv ));
int nrwabs P((int rw , void *buf , unsigned count , long recno , int drive ));
void get_block P((long num ));
void put_block P((long num ));
void check_lrecno P((void ));
void warn P((void ));
#undef P
void main(argc,argv)
int argc;
char **argv;
{
extern int optind,opterr;
extern char *optarg;
extern int __mint;
long hderr;
int c ;
static char err=0;
int i,j;
_BPB *bpb;
unsigned short ioff,zone1;
super_block *sblk=(super_block *)block_buf,csblk;
d_inode *rip=(d_inode *)block_buf;
d_inode2 *ripn=(d_inode2 *)block_buf;
dir_struct *dir=(dir_struct *)block_buf;
unsigned short *srt=(unsigned short *)block_buf;
long icount, zcount;
struct
{
long start;
long finish;
char shadow;
char scsiz;
} pp;
if(__mint==0)
{
fprintf(stderr,"Error: MiNT not active.\n");
exit(1);
}
/* Parse command-line options */
opterr=0;
while((c=getopt(argc,argv,"b:B:i:I:n:pPSZztV"))!=EOF)
{
switch(c){
case 'B':
case 'b':
numblocks=atol(optarg);
break;
case 'n':
incr=atol(optarg);
break;
case 'i':
case 'I':
numinodes=atol(optarg);
break;
case 'P':
protect=1;
break;
case 'p':
protect=2;
break;
case 'S':
sonly=1;
break;
case 'Z':
protect=1;
break;
case 'z':
protect=2;
break;
case 'V':
v2=1;
break;
case 't':
tst=1;
break;
case '?':
err=1;
break;
}
}
if(argc-optind!=1 || err)
{
fprintf(stderr,"Minix-compatible filesystem initializer\n");
fprintf(stderr,"Copyright S N Henson 1991,1992,1993\n");
fprintf(stderr,"Version 0.26\n");
fprintf(stderr,"Usage\t(auto)\t: minit drive\n");
fprintf(stderr,"\t(manual): minit -b blocks -i inodes drive\n");
fprintf(stderr,"Also :\t-S only write out super-block\n");
fprintf(stderr,"\t-P/-Z protect filesystem with null disk\n");
fprintf(stderr,"\t-p/-z make null disk of existing filestystem\n");
fprintf(stderr,"\t-V make a V2 filesystem\n");
fprintf(stderr,"\t-n dirincrement\n");
fprintf(stderr,"\t-t test mode (no writing)\n");
exit(1);
}
drive=(argv[optind][0] & ~32)-'A' ;
bpb=Getbpb(drive);
/* Sanity checking time */
if((incr < 1) || (incr > 16) || ( (incr) & (incr-1) ) )
{
fprintf(stderr,"Dirincrement must be a power of two between\n");
fprintf(stderr,"1 and 16 (inclusive)\n");
exit(1);
}
if( (numinodes < 0) || (numinodes > 65535) )
{
fprintf(stderr,"Need at least 1 and no more than 65535 inodes\n");
exit(1);
}
if(protect==2 && bpb->recsiz!=512)
{
fprintf(stderr,"Sorry can't add protection to this filesytem.\n");
fprintf(stderr,"Sector size not 512 bytes.\n");
exit(1);
}
/* Test for physical partition */
if(!Dcntl(0x109,argv[optind],&pp) && pp.start!=-1)
{
long tstack;
hdinf.start=pp.start;
hdinf.size=pp.finish-hdinf.start+1;
hdinf.scsiz=pp.scsiz;
hdinf.major = pp.shadow;
hdinf.drive = drive;
tstack=Super(0l);
if(init_icd()==2)
{
Super(tstack);
fprintf(stderr,"Can't kludge ICD bug\n");
exit(1);
}
Super(tstack);
hdinf.rwmode = RW_PHYS;
if(hdinf.start > 0xfffe)
{
if(no_plrecno(hdinf.major))
fprintf(stderr,"Cannot access Drive %c:\n",drive+'A');
hdinf.rwmode |= RW_LRECNO;
}
}
else
{
pp.start=-1;
if( (hderr=get_hddinf(drive,&hdinf,0)) )
{
fprintf(stderr,"Cannot access Drive %c: %s\n",drive+'A',
hdd_err[hderr]);
exit(1);
}
}
if(tst)
{
struct hdinfo hdinf2;
unsigned int llrecno,xhret,no_phys;
no_phys=0;
if(pp.start==-1)
{
llrecno=no_lrecno(drive);
if(llrecno && llrecno!=3)
fprintf(stderr,"Logical lrecno error\n");
else fprintf(stderr,"Logical lrecno OK\n");
}
else
{
fprintf(stderr,"Physical Partition\n");
hdinf2=hdinf;
}
if( (no_phys=get_hddinf(drive,&hdinf2,1) ) )
fprintf(stderr,"Can't get physical drive info: %s\n",hdd_err[no_phys]);
else if( (hdinf2.rwmode & RW_MODE) != RW_XHDI )
{
llrecno=no_plrecno(hdinf2.major);
if(llrecno && llrecno!=3)
fprintf(stderr,"Physical lrecno error\n");
else fprintf(stderr,"Physical lrecno OK\n");
}
if( (xhret=XHGetVersion()) ) fprintf(stderr,"XHDI supported"
" version %x.%02x\n", xhret>>8,xhret & 0xff);
else fprintf(stderr,"XHDI not supported\n");
if(!no_phys)
{
fprintf(stderr,"Partition start: %ld\n",hdinf2.start);
if(hdinf2.size)
fprintf(stderr,"Partition size: %ld\n",hdinf2.size);
if( (hdinf2.rwmode & RW_MODE) == RW_PHYS)
{
unsigned ddev;
char *sbus;
ddev=hdinf2.minor;
fprintf(stderr,"Unit number %d\n",ddev);
if( ddev & PUN_IDE) sbus="IDE";
else
{
if( ddev & PUN_SCSI) sbus="SCSI";
else sbus="ACSI";
}
fprintf(stderr,"%s bus: device %d.(",sbus,
ddev & PUN_UNIT);
if(ddev & PUN_REMOVABLE) fprintf(stderr,"Removable)\n");
else fprintf(stderr,"Non-removable)\n");
}
else fprintf(stderr,"Major number %d Minor number %d\n",
hdinf2.major,hdinf2.minor);
}
}
if(!numblocks) numblocks=hdinf.size>>hdinf.scsiz;
else if(hdinf.size && (numblocks > hdinf.size>>hdinf.scsiz))
{
fprintf(stderr,"Partition has only %ld blocks\n",
hdinf.size>>hdinf.scsiz);
exit(1);
}
/* read in boot sector */
get_block(0);
/* If size of partition not known try BPB/boot sector */
if(!numblocks)
{
if(!bpb || (bpb->recsiz & 511))
{
fprintf(stderr,"Can't figure out partition size: "
"try the -b option\n");
exit(1);
}
numblocks=( (block_buf[19]+( ((long)block_buf[20])<<8))*
bpb->recsiz)>>10;
if(numbloc